#include <ctype.h>
#include <string.h>
#include "../../../vcd-common-api/vcd-common.h"
#include "../../vcd-message-dialog.h"
#include "vcd-wire.h"

#define ETH0 "eth0"

typedef struct netcard{
    gchar name[16];
    gchar onboot[16];
    gchar type[16];
    gchar bootproto[16];
    gchar ip[16];
    gchar netmask[16];
    gchar gateway[16];
    gchar dns1[16];
    gchar dns2[16];
}netcard;

typedef struct resolv_dns{
    gchar **dns;
    gint count;
}resolv_dns;

typedef struct route_gateway{
    gchar iface_name[16];
    gchar gateway[16];
}route_gateway;

typedef struct gateway_table{
    route_gateway **r_gateway;
    gint count;
}gateway_table;

netcard* g_netard = NULL;
gint     g_netard_num = 0;

resolv_dns *g_resolv_dns = NULL;

gateway_table *g_gateway_table = NULL;

typedef struct{
    GtkWidget *tab_ip;
    GtkWidget *tab_netmask;
    GtkWidget *tab_gateway;
    GtkWidget *tab_dns1;
    GtkWidget *tab_dns2;
    GtkWidget *tab4_saveBtn;
    GtkWidget *combo_DHCP;
    GtkWidget *combo_netcard;
} Set_Eth0;
Set_Eth0 eth_wire;

void set_entry_focus(gboolean focus);

int get_card_from_script(gchar* name, netcard* ptr_card);

int save_dns_to_reslove(const gchar* dns);
int update_ip_netmask_gateway_by_name(const gchar* name);

gboolean netcard_is_dhcp(netcard *card);
int get_gateway_table(void);

void free_gateway_table(gateway_table *table);

void free_resolv_dns(resolv_dns *ptr_dns);
int get_dns_from_resolv(void);

int get_real_netcard_info(netcard** pp_card, gint *p_count);
int get_system_netcards(void);

int check_entry_infomation(void);

int set_netcard_to_dhcp(const gchar* name);
int set_netcard_to_static(const gchar* name);
void update_entry_by_netcard(netcard *card_show);
int check_dns1_dns2(void);

void button_set_netcard(void);
void changeDHCP(void);

void change_netcard(void);

void free_gateway_table(gateway_table *table)
{
    if(table == NULL){
        return;
    }

    for(gint i = 0; i < table->count; ++i){
        g_free(table->r_gateway[i]);
    }
    g_free(table->r_gateway);
    g_free(table);
}

int get_gateway_table(void)
{
    gateway_table* table = g_malloc0(sizeof(gateway_table));
    if(table == NULL){
        return -1;
    }

    const gchar *cmd = "LC_ALL=C route -n|tail -n +3|awk '{print $1,$2,$8}'";
    gchar line[4096];
    FILE *f = popen(cmd, "r");
    if(f == NULL){
        LOG_ERROR("popen %s fail:%m", cmd);
        g_free(table);
        return -1;
    }

    char Destination[16];
    char gateway[16];
    char iface_name[16];

    while(!feof(f) && !ferror(f)){
        memset(line, 0, sizeof(line));
        char *p = fgets(line, sizeof(line), f);
        if(p == NULL){
            break;
        }

        memset(Destination, 0, sizeof(Destination));
        memset(gateway, 0, sizeof(gateway));
        memset(iface_name, 0, sizeof(iface_name));

        int n = sscanf(line, "%[^ ] %[^ ] %s", Destination, gateway, iface_name);
        if(n != 3){
            continue;
        }

        if(strcmp(Destination, "0.0.0.0") != 0){
            continue;
        }

        route_gateway* y = g_malloc0(sizeof(route_gateway));
        if(y == NULL){
            continue;
        }

        strncpy(y->gateway, gateway, sizeof(y->gateway));
        strncpy(y->iface_name, iface_name, sizeof(y->iface_name));

        route_gateway **pp = NULL;
        if(table->r_gateway == NULL){
            pp = (route_gateway**)g_malloc0(sizeof(route_gateway*));
        }else{
            pp = (route_gateway**)g_realloc(table->r_gateway, sizeof(route_gateway*) * (table->count + 1));
        }

        if(pp == NULL){
            goto fail;
        }

        pp[table->count] = y;
        table->count++;

        table->r_gateway = pp;
    }

    pclose(f);

    //free old
    free_gateway_table(g_gateway_table);

    //set to new
    g_gateway_table = table;
    return 0;
fail:
    free_gateway_table(table);
    pclose(f);
    return -1;
}

void free_resolv_dns(resolv_dns *ptr_dns)
{
    if(ptr_dns == NULL){
        return;
    }

    for(gint i = 0; i < ptr_dns->count; ++i){
        g_free(ptr_dns->dns[i]);
    }

    g_free(ptr_dns);
}

int get_dns_from_resolv(void)
{
    resolv_dns *ptr_dns = NULL;
    ptr_dns = g_malloc0(sizeof(resolv_dns));
    if(ptr_dns == NULL){
        LOG_ERROR("g_malloc error:%m");
        return -1;
    }

    FILE* f = fopen("/etc/resolv.conf", "r");
    if(f == NULL){
        g_free(ptr_dns);
        return -1;
    }

    gchar line[4096];
    while(!feof(f) && !ferror(f)){
        memset(line, 0, sizeof(line));
        char* p = fgets(line, sizeof(line), f);
        if(p == NULL){
            break;
        }

        //skip space
        while(isspace(*p)){
            ++p;
        }

        p = strlower(p);

        char* ps = strstr(p, "nameserver");
        if(ps == NULL){
            continue;
        }

        //skip space
        ps += strlen("nameserver");
        while(isspace(*ps)){
            ++ps;
        }

        ps[strlen(ps) - 1] = '\0';

        char *dns = g_malloc(16);
        if(dns == NULL){
            continue;
        }

        strncpy(dns, ps,  16);

        if(ptr_dns->dns == NULL){
            ptr_dns->dns = (gchar**)g_malloc(sizeof(gchar*));
        }else{
            gchar **d = (gchar**)g_realloc(ptr_dns->dns, sizeof(gchar*) * (ptr_dns->count + 1));
            if(d == NULL){
                goto fail;
            }
            ptr_dns->dns = d;
        }

        ptr_dns->dns[ptr_dns->count] = dns;
        ptr_dns->count++;
    }

    fclose(f);

    //free old
    free_resolv_dns(g_resolv_dns);

    //set to new
    g_resolv_dns = ptr_dns;
    return 0;
fail:
    fclose(f);
    free_resolv_dns(ptr_dns);
    return -1;
}

int get_card_from_script(gchar* name, netcard* ptr_card)
{
    if (ptr_card == NULL || name == NULL)
        return -1;

    memset(ptr_card, 0, sizeof(netcard));
    strncpy(ptr_card->name, name, sizeof(ptr_card->name));

    gchar path[255];
    snprintf(path, sizeof(path),"/etc/sysconfig/network-scripts/ifcfg-%s", name);
    M_DEBUG(path);
    FILE* f = fopen(path, "r");
    if (!f)
        return -1;
    gchar line[4096];
    while (!feof(f) && !ferror(f)) {
        memset(line, 0, sizeof(line));
        gint pre_len = 0;
        char* p = fgets(line, sizeof(line), f);
        if(p == NULL){
            break;
        }
        p[strlen(p) - 1]='\0';
        //skip space
        while(isspace(*p)){
            ++p;
        }

        p = strlower(p);

        char *p1 = strchr(p, '=');

        //skip invalid lines
        if(p1 == NULL){
            continue;
        }

        pre_len = p1 - p;
        ++p1;
        if(strncasecmp(p, "device", pre_len) == 0){
            if(strcasecmp(p1, name) != 0){
                return -1;
            }
        }

        if(strncasecmp(p, "bootproto", pre_len) == 0){
            strncpy(ptr_card->bootproto, p1, sizeof(ptr_card->bootproto));
            continue;
        }

        if(strncasecmp(p, "onboot", pre_len) == 0){
            strncpy(ptr_card->onboot, p1, sizeof(ptr_card->onboot));
            continue;
        }

        if(strncasecmp(p, "type", pre_len) == 0){
            strncpy(ptr_card->type, p1, sizeof(ptr_card->type));
            continue;
        }

        if(strncasecmp(p, "ipaddr", pre_len) == 0){
            strncpy(ptr_card->ip, p1, sizeof(ptr_card->ip));
            continue;
        }

        if(strncasecmp(p, "netmask", pre_len) == 0){
            strncpy(ptr_card->netmask, p1, sizeof(ptr_card->netmask));
            continue;
        }

        if(strncasecmp(p, "gateway", pre_len) == 0){
            strncpy(ptr_card->gateway, p1, sizeof(ptr_card->gateway));
            continue;
        }

        if(strncasecmp(p, "dns1", pre_len) == 0){
            strncpy(ptr_card->dns1, p1, sizeof(ptr_card->dns1));
            continue;
        }

        if(strncasecmp(p, "dns2", pre_len) == 0){
            strncpy(ptr_card->dns2, p1, sizeof(ptr_card->dns2));
            continue;
        }
    }

    return 0;
}

int get_real_netcard_info(netcard** pp_card, gint *p_count)
{
    #ifdef __linux__
    gint i = 0;
    struct ifreq * ifr = NULL;
    struct ifconf ifc;
    netcard* ptr_card = NULL;
    gint card_count = 0;

    if (pp_card == NULL || p_count == NULL)
        return -1;

    //初始化ifconf
    char buf[4096];
    memset(buf, 0, sizeof(buf));
    ifc.ifc_len = sizeof(buf);
    ifc.ifc_buf = buf;

    int sock = socket(AF_INET, SOCK_DGRAM, 0);
    if (sock < 0) {
        LOG_ERROR("create socket failed:%m");
        return -1;
    }

    if (ioctl(sock, SIOCGIFCONF, (char *)&ifc) < 0) {
        LOG_ERROR("ioctl-conf fail:%m");
        goto fail;
    }

    card_count = ifc.ifc_len/sizeof(struct ifreq);

    //LOG_DEBUG("system have %d network cards", card_count);

    //only fetch max 10
    if (card_count > 10)
        card_count = 10;

    ptr_card = g_malloc0(card_count * sizeof(netcard));
    if (ptr_card == NULL)
        goto fail;

    ifr = (struct ifreq*)buf;
    for (i = 0; i < card_count; i++) {
        netcard* card = ptr_card + i;

        //网卡名
        strncpy(card->name, ifr->ifr_name, sizeof(card->name));

        //M_DEBUG("card name list %d = %s", i + 1, card->name);

        //网卡本地IP地址
        if (ioctl(sock, SIOCGIFADDR, ifr) >= 0) {
            strncpy(card->ip, inet_ntoa(((struct sockaddr_in*)&(ifr->ifr_addr))->sin_addr), sizeof(card->ip));
        } else {
            LOG_ERROR("ioctl SIOCGIFADDR error:%m");
        }

        //网卡子网掩码地址
        if (ioctl(sock, SIOCGIFNETMASK, ifr) >= 0) {
            strncpy(card->netmask, inet_ntoa(((struct sockaddr_in*)&(ifr->ifr_netmask))->sin_addr), sizeof(card->netmask));
        } else {
            LOG_ERROR("	ioctl SIOCGIFNETMASK error:%m");
        }

        ifr++;
    }
    close(sock);

    *pp_card  = ptr_card;
    *p_count = card_count;
    return 0;
fail:
    close(sock);
#endif
    return -1;
}


int get_system_netcards(void)
{
    gint i = 0, j = 0;
    netcard* ptr_card = NULL;
    gint card_count = 0;

    int ret = get_real_netcard_info(&ptr_card, &card_count);
    if (ret != 0)
        return -1;

    get_gateway_table();
    get_dns_from_resolv();

    //fill bootproto, gateway and dns
    for (i = 0; i < card_count; i++) {
        netcard* card = ptr_card + i;
        netcard card_stript;
        int ret = get_card_from_script(card->name, &card_stript);
        if (ret != 0)
            continue;

        //bootproto
        strncpy(card->bootproto, card_stript.bootproto, sizeof(card->bootproto));

        //gateway
        if (strlen(card_stript.gateway) == 0) {
            if (g_gateway_table) {
                for (j = 0; j < g_gateway_table->count; ++j) {
                    route_gateway* y = g_gateway_table->r_gateway[j];
                    if (strcmp(y->iface_name, card->name) == 0) {
                        strncpy(card->gateway, y->gateway, sizeof(card->gateway));
                    }
                }
            }
        } else {
            strncpy(card->gateway, card_stript.gateway, sizeof(card->gateway));
        }

        //dns1
        if (strlen(card_stript.dns1) == 0) {
            if (g_resolv_dns && g_resolv_dns->count >= 1) {
                strncpy(card->dns1, g_resolv_dns->dns[0], sizeof(card->dns1));
            }
        }  else {
            strncpy(card->dns1, card_stript.dns1, sizeof(card->dns1));
        }

        //dns2
        if (strlen(card_stript.dns2) == 0) {
            if (g_resolv_dns && g_resolv_dns->count >= 2) {
                strncpy(card->dns2, g_resolv_dns->dns[1], sizeof(card->dns2));
            }
        } else {
            strncpy(card->dns2, card_stript.dns2, sizeof(card->dns2));
        }
    }

    //free old
    g_free(g_netard);
    g_netard_num = 0;

    //update to new
    g_netard = ptr_card;
    g_netard_num = card_count;

    return 0;
}

char *get_nowip(void)
{    
    netcard *card = NULL;
    gint count = 0;
    int ret = get_real_netcard_info(&card, &count);
    if (ret != 0) {
        return strdup("127.0.0.1");
    }

    gint i = 0;
    for(i = 0; i < count; ++i){
        netcard *d = card + i;
        if(strcmp(d->name, "lo") != 0){
            g_free(card);
            return strdup(d->ip);
        }
    }

    g_free(card);
    return strdup("127.0.0.1");
}

int get_local_ip(char *ip)
{
#ifdef __WIN32__
    WSADATA wsaData;
    char name[155];
    char *ip_tmp;
    PHOSTENT hostinfo;
    if (WSAStartup(MAKEWORD(2, 0), &wsaData) == 0)
    {
        if (gethostname(name, sizeof(name)) == 0)
        {
            if ((hostinfo = gethostbyname(name)) != NULL)
            {
                ip_tmp = inet_ntoa(*(struct in_addr *)*hostinfo->h_addr_list);
                strcpy(ip, ip_tmp);
                M_DEBUG(" local IP: %s ", ip);
            }
        }
        WSACleanup();
        return 0;
    }
    return -1;
#else
    netcard* ptr_card = NULL;
    gint card_count = 0;

    int ret = get_real_netcard_info(&ptr_card, &card_count);
    if (ret != 0) {
        return -1;
    }

    gint i = 0;
    for (i = 0; i < card_count; ++i) {
        netcard* d = ptr_card + i;
        if (strcmp(d->name, "lo") != 0) {
            strcpy(ip, d->ip);
            return 0;
        }
    }

    return -1;
#endif
}


gboolean netcard_is_dhcp(netcard *card)
{    
    return strcasecmp(card->bootproto, "dhcp") == 0;
}

int update_ip_netmask_gateway_by_name(const gchar* name)
{
    netcard* ptr_card = NULL;
    gint card_count = 0;
    gint i = 0;
    int ret = get_real_netcard_info(&ptr_card, &card_count);
    if (ret != 0) {
        return -1;
    }

    netcard* card = NULL;
    for (i = 0; i < card_count; ++i) {
        netcard* d = ptr_card + i;
        if (strncmp(d->name, name, sizeof(ptr_card->name)) == 0) {
            card = d;
            break;
        }
    }

    if (card) {
        gtk_entry_set_text(GTK_ENTRY(eth_wire.tab_ip), card->ip);
        gtk_entry_set_text(GTK_ENTRY(eth_wire.tab_netmask), card->netmask);
    } else {
        gtk_entry_set_text(GTK_ENTRY(eth_wire.tab_ip), "");
        gtk_entry_set_text(GTK_ENTRY(eth_wire.tab_netmask), "");
    }

    get_gateway_table();

    route_gateway* rg = NULL;
    for (i = 0; i < g_gateway_table->count; ++i) {
        route_gateway* y = g_gateway_table->r_gateway[i];
        if (strncmp(y->iface_name, name, sizeof(y->iface_name)) == 0) {
            rg = y;
            break;
        }
    }

    if (rg) {
        gtk_entry_set_text(GTK_ENTRY(eth_wire.tab_gateway), rg->gateway);
    } else {
        gtk_entry_set_text(GTK_ENTRY(eth_wire.tab_gateway), "");
    }
    return 0;
}

int save_dns_to_reslove(const gchar* dns)
{
    gint i = 0;
    //already exit, return
    if (g_resolv_dns) {
        for (i = 0; i < g_resolv_dns->count; ++i) {
            if (strcmp(g_resolv_dns->dns[i], dns) == 0) {
                return 0;
            }
        }
    }

    //add to tail
    FILE *pf = fopen("/etc/resolv.conf", "a+");
    if (pf == NULL) {
        return -1;
    }

    fputs("\nnameserver ", pf);
    fputs(dns, pf);
    fputs("\n", pf);
    fclose(pf);
    pf = NULL;
    return 0;
}

int check_dns1_dns2(void)
{
    #ifdef __linux__
    int ret = 0;
    gchar err[255];
    unsigned char buf[sizeof(struct in6_addr)];
    const gchar* dns1 = gtk_entry_get_text(GTK_ENTRY(eth_wire.tab_dns1));
    const gchar* dns2 = gtk_entry_get_text(GTK_ENTRY(eth_wire.tab_dns2));

    if (dns1 && dns1[0] != 0) {
        ret = inet_pton(AF_INET, dns1, buf);
        if(ret != 1){
            snprintf(err, sizeof(err), "错误的 dns1:%s", dns1);
            message_box(err);
            return -1;
        }
    }

    if (dns2 && dns2[0] != 0) {
        ret = inet_pton(AF_INET, dns2, buf);
        if (ret != 1) {
            snprintf(err, sizeof(err), "错误的 dns2:%s", dns2);
            message_box(err);
            return -1;
        }
    }
    #endif
    return 0;
}

int set_netcard_to_dhcp(const gchar* name)
{
    //check dns1 dns2 first
    int ret = check_dns1_dns2();
    if(ret != 0) {
        return -1;
    }
    const gchar* dns1 = gtk_entry_get_text(GTK_ENTRY(eth_wire.tab_dns1));
    const gchar* dns2 = gtk_entry_get_text(GTK_ENTRY(eth_wire.tab_dns2));
    if (dns1 && dns1[0] != 0) {
        save_dns_to_reslove(dns1);
    }
    if (dns2 && dns2[0] != 0) {
        save_dns_to_reslove(dns2);
    }

    gchar path[255];
    snprintf(path, sizeof(path), "/etc/sysconfig/network-scripts/ifcfg-%s", name);

    FILE *fp = fopen(path, "w+");
    if (NULL == fp) {
        char err[1024];
        snprintf(err, sizeof(err),"open file:%s fail:%m\n", path);
        LOG_ERROR(err);
        message_box(err);
        return -1;
    }

    gchar buf[4096];
    snprintf(buf, sizeof(buf),"DEVICE=%s\nBOOTPROTO=dhcp\nONBOOT=yes\nTYPE=Ethernet\n", name);
    fputs(buf, fp);

    fclose(fp);
    fp = NULL;

    ret = system("systemctl restart network.service");
    if (ret != 0) {
        LOG_ERROR("systemctl restart network.service error");
    }

    update_ip_netmask_gateway_by_name(name);
    if (ret == 0) {
        message_box("操作成功！");
    } else {
        message_box("无网络连接！");
    }
    return 0;
}

int check_entry_infomation(void)
{
    #ifdef __linux__
    const char* ip = gtk_entry_get_text(GTK_ENTRY(eth_wire.tab_ip));
    const char* netmask = gtk_entry_get_text(GTK_ENTRY(eth_wire.tab_netmask));
    const char* gateway = gtk_entry_get_text(GTK_ENTRY(eth_wire.tab_gateway));

    int ret = 0;
    gchar err[255];
    unsigned char buf[sizeof(struct in6_addr)];

    ret = inet_pton(AF_INET, ip, buf);
    if (ret != 1) {
        snprintf(err, sizeof(err), "错误的ip地址:%s", ip);
        message_box(err);
        return -1;
    }

    ret = inet_pton(AF_INET, netmask, buf);
    if (ret != 1) {
        snprintf(err, sizeof(err), "错误的掩码:%s", netmask);
        message_box(err);
        return -1;
    }

    ret = inet_pton(AF_INET, gateway, buf);
    //网关可以为空
    if (ret != 1 && strlen(gateway) != 0) {
        snprintf(err, sizeof(err), "错误的网关:%s", gateway);
        message_box(err);
        return -1;
    }

    return check_dns1_dns2();
    #endif
    return -1;
}

int set_netcard_to_static(const gchar* name)
{
    int ret = check_entry_infomation();
    if (ret != 0)
        return -1;

    const gchar *ip = gtk_entry_get_text(GTK_ENTRY(eth_wire.tab_ip));
    const gchar *netmask = gtk_entry_get_text(GTK_ENTRY(eth_wire.tab_netmask));
    const gchar *gateway =gtk_entry_get_text(GTK_ENTRY(eth_wire.tab_gateway));
    const gchar *dns1 = gtk_entry_get_text(GTK_ENTRY(eth_wire.tab_dns1));
    const gchar *dns2 =gtk_entry_get_text(GTK_ENTRY(eth_wire.tab_dns2));

    char DNS_string[80] = {0};
    memset(DNS_string, 0, sizeof(DNS_string));
    if (dns1 && dns1[0] != 0) {
        strcat(DNS_string, "DNS1=");
        strcat(DNS_string, dns1);
        strcat(DNS_string, "\n");
    }

    if (dns2 && dns2[0] != 0) {
        strcat(DNS_string, "DNS2=");
        strcat(DNS_string, dns2);
        strcat(DNS_string, "\n");
    }

    char Manual_string[500] = {0};
    snprintf(Manual_string, sizeof(Manual_string),
             "DEVICE=%s\nBOOTPROTO=static\nONBOOT=yes\nTYPE=Ethernet\nIPADDR=%s\nNETMASK=%s\nGATEWAY=%s\n",
             name, ip, netmask, gateway);

    gchar path[255];
    snprintf(path, sizeof(path), "/etc/sysconfig/network-scripts/ifcfg-%s", name);

    FILE *fp = fopen(path, "w+");
    if (NULL == fp) {
        char err[1024];
        snprintf(err, sizeof(err),"open file:%s fail:%m\n", path);
        LOG_ERROR(err);
        message_box(err);
        return -1;
    }

    fputs(Manual_string, fp);
    if(DNS_string[0] != 0) {
        fputs(DNS_string, fp);
    }

    fclose(fp);
    fp = NULL;

    system("systemctl restart network.service");
    update_ip_netmask_gateway_by_name(name);

    //check whether is effice
    const gchar *ip2 = gtk_entry_get_text(GTK_ENTRY(eth_wire.tab_ip));
    const gchar *netmask2 = gtk_entry_get_text(GTK_ENTRY(eth_wire.tab_netmask));
    const gchar *gateway2 =gtk_entry_get_text(GTK_ENTRY(eth_wire.tab_gateway));

    if (strcmp(ip2, ip) != 0 ||
            strcmp(netmask2, netmask) != 0 ||
            strcmp(gateway2, gateway) != 0) {
        message_box("操作失败！");
    } else {
        message_box("操作成功！");
    }
    return 0;
}

void update_entry_by_netcard(netcard *card_show)
{
    int active_index = 1;//
    gboolean focus = TRUE;

    if (netcard_is_dhcp(card_show)) {
        active_index = 0;
        focus = FALSE;
    }

    //will call changeDHCP
    gtk_combo_box_set_active(GTK_COMBO_BOX((GtkComboBox *)eth_wire.combo_DHCP), active_index);

    gtk_entry_set_text(GTK_ENTRY(eth_wire.tab_ip),      card_show->ip);
    gtk_entry_set_text(GTK_ENTRY(eth_wire.tab_netmask), card_show->netmask);
    gtk_entry_set_text(GTK_ENTRY(eth_wire.tab_gateway), card_show->gateway);
    gtk_entry_set_text(GTK_ENTRY(eth_wire.tab_dns1),    card_show->dns1);
    gtk_entry_set_text(GTK_ENTRY(eth_wire.tab_dns2),    card_show->dns2);

    set_entry_focus(focus);
}

void button_set_netcard(void)
{
    gtk_widget_set_sensitive(eth_wire.tab4_saveBtn, FALSE);

    const gchar *name = gtk_combo_box_text_get_active_text((GtkComboBoxText *)eth_wire.combo_netcard);
    const gchar *dhcp = gtk_combo_box_text_get_active_text((GtkComboBoxText *)eth_wire.combo_DHCP);

    if (strcmp(dhcp, "自动") == 0) {
        set_netcard_to_dhcp(name);
    } else if (strcmp(dhcp, "手动") == 0) {
        set_netcard_to_static(name);
    } else {
        message_box("invalid bootproto");
    }

    gtk_widget_set_sensitive(eth_wire.tab4_saveBtn, TRUE);
}

void set_entry_focus(gboolean focus)
{
    gtk_widget_set_can_focus(eth_wire.tab_ip, focus);
    gtk_widget_set_can_focus(eth_wire.tab_netmask, focus);
    gtk_widget_set_can_focus(eth_wire.tab_gateway, focus);
    gtk_widget_set_can_focus(eth_wire.tab_dns1, focus);
    gtk_widget_set_can_focus(eth_wire.tab_dns2, focus);
}

void set_network_information(void)
{
    get_system_netcards();

    gint i = 0;

    gtk_combo_box_text_remove_all(GTK_COMBO_BOX_TEXT((GtkComboBoxText *)eth_wire.combo_netcard));
    
    M_DEBUG("net card num = %d", g_netard_num);
    
    if (g_netard_num > 1) {
    
        for (i = 0; i < g_netard_num; ++i) {
            netcard *card = &g_netard[i];
            if(strcasecmp(card->name, "lo") == 0)
                continue;
            gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT((GtkComboBoxText *)eth_wire.combo_netcard), NULL, card->name);        
        }
    } else {
        gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT((GtkComboBoxText *)eth_wire.combo_netcard), NULL, "eth0");        
    }

    //will call channge_netcard
    gtk_combo_box_set_active(GTK_COMBO_BOX((GtkComboBox *)eth_wire.combo_netcard), 0);
}

void changeDHCP(void)
{
    const char *DHCP = gtk_combo_box_text_get_active_text((GtkComboBoxText *)(eth_wire.combo_DHCP));
    if (DHCP == NULL)
        return;

    const gchar *btn_label = "应用";
    gboolean focus = TRUE;
    const gchar *css = "entry{ background:rgb(255,255,255);"
                 "border:1px solid rgb(204,204,204);"
                 "border-radius:0px;"
                 "padding-left:12px}";
    if (strcmp(DHCP, "自动") == 0){
        btn_label = "刷新";
        focus = FALSE;
        css = "entry{ background:rgb(220,220,220);"
              "border:1px solid rgb(204,204,204);"
              "border-radius:0px;"
              "padding-left:12px}";

    }

    gtk_button_set_label((GtkButton *)eth_wire.tab4_saveBtn, btn_label);
    set_entry_focus(focus);
    set_css(eth_wire.tab_ip,        css);
    set_css(eth_wire.tab_netmask,   css);
    set_css(eth_wire.tab_gateway,   css);
    set_css(eth_wire.tab_dns1,      css);
    set_css(eth_wire.tab_dns2,      css);
}

void change_netcard(void)
{
    const char *name = gtk_combo_box_text_get_active_text((GtkComboBoxText *)(eth_wire.combo_netcard));
    if (name == NULL || name[0] == 0)
        return;

    get_system_netcards();

    gint i = 0;
    for (i = 0; i < g_netard_num; ++i) {
        netcard *card = g_netard + i;
        if (strcasecmp(card->name, name) == 0) {
            update_entry_by_netcard(card);
            return;
        }
    }
}

GtkWidget *get_sys_wire_info_fix(void)
{
    GtkWidget *fix_network_wired = gtk_fixed_new();
    GtkWidget *tab_netcard, *tab_bootproto, *tab_ip, *tab_netmask, *tab_gateway, *tab_dns1, *tab_dns2;

    eth_wire.tab_ip         = gtk_entry_new();
    eth_wire.tab_netmask    = gtk_entry_new();
    eth_wire.tab_gateway    = gtk_entry_new();
    eth_wire.tab_dns1       = gtk_entry_new();
    eth_wire.tab_dns2       = gtk_entry_new();

    gtk_entry_set_max_length(GTK_ENTRY(eth_wire.tab_ip),       16);
    gtk_entry_set_max_length(GTK_ENTRY(eth_wire.tab_netmask),  16);
    gtk_entry_set_max_length(GTK_ENTRY(eth_wire.tab_gateway),  16);
    gtk_entry_set_max_length(GTK_ENTRY(eth_wire.tab_dns1),     16);
    gtk_entry_set_max_length(GTK_ENTRY(eth_wire.tab_dns2),     16);

    tab_netcard     = gtk_label_new("      网卡");
    tab_bootproto   = gtk_label_new("      配置");
    tab_ip          = gtk_label_new("    IP地址");
    tab_netmask     = gtk_label_new("子网掩码");
    tab_gateway     = gtk_label_new("      网关");
    tab_dns1        = gtk_label_new("    DNS1");
    tab_dns2        = gtk_label_new("    DNS2");

    eth_wire.combo_netcard = gtk_combo_box_text_new();
    gtk_widget_set_size_request(eth_wire.combo_netcard, 173, 20);

    eth_wire.combo_DHCP = gtk_combo_box_text_new();
    gtk_widget_set_size_request(eth_wire.combo_DHCP, 173, 20);

    gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT((GtkComboBoxText *)eth_wire.combo_DHCP), NULL, "自动");
    gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT((GtkComboBoxText *)eth_wire.combo_DHCP), NULL, "手动");

    eth_wire.tab4_saveBtn = gtk_button_new_with_label("刷新");
    gtk_widget_set_size_request(eth_wire.tab4_saveBtn, 100, 20);
    gtk_button_set_relief(GTK_BUTTON(eth_wire.tab4_saveBtn), GTK_RELIEF_NONE);

    set_css(eth_wire.tab_ip, "entry{ background:rgb(250,250,250);"
                             "border:1px solid rgb(204,204,204);"
                             "border-radius:0px;"
                             "padding-left:12px}");
    set_css(eth_wire.tab_netmask, "entry{ background:rgb(250,250,250);"
                                  "border:1px solid rgb(204,204,204);"
                                  "border-radius:0px;"
                                  "padding-left:12px}");
    set_css(eth_wire.tab_gateway, "entry{ background:rgb(250,250,250);"
                                  "border:1px solid rgb(204,204,204);"
                                  "border-radius:0px;"
                                  "padding-left:12px}");
    set_css(eth_wire.tab_dns1, "entry{ background:rgb(250,250,250);"
                               "border:1px solid rgb(204,204,204);"
                               "border-radius:0px;"
                               "padding-left:12px}");
    set_css(eth_wire.tab_dns2, "entry{ background:rgb(250,250,250);"
                               "border:1px solid rgb(204,204,204);"
                               "border-radius:0px;"
                               "padding-left:12px}");

    gtk_combo_box_set_active(GTK_COMBO_BOX((GtkComboBox *)eth_wire.combo_DHCP), 0);

    gtk_fixed_put((GtkFixed *)fix_network_wired, tab_netcard, 100, 48);
    gtk_fixed_put((GtkFixed *)fix_network_wired, tab_bootproto, 100, 90);
    gtk_fixed_put((GtkFixed *)fix_network_wired, tab_ip, 100, 132);
    gtk_fixed_put((GtkFixed *)fix_network_wired, tab_netmask, 100, 174);
    gtk_fixed_put((GtkFixed *)fix_network_wired, tab_gateway, 100, 216);
    gtk_fixed_put((GtkFixed *)fix_network_wired, tab_dns1, 100, 258);
    gtk_fixed_put((GtkFixed *)fix_network_wired, tab_dns2, 100, 300);

    gtk_fixed_put((GtkFixed *)fix_network_wired, eth_wire.combo_netcard,  200, 40);
    gtk_fixed_put((GtkFixed *)fix_network_wired, eth_wire.combo_DHCP,  200, 82);
    gtk_fixed_put((GtkFixed *)fix_network_wired, eth_wire.tab_ip, 200, 124);
    gtk_fixed_put((GtkFixed *)fix_network_wired, eth_wire.tab_netmask, 200, 166);
    gtk_fixed_put((GtkFixed *)fix_network_wired, eth_wire.tab_gateway, 200, 208);
    gtk_fixed_put((GtkFixed *)fix_network_wired, eth_wire.tab_dns1, 200, 250);
    gtk_fixed_put((GtkFixed *)fix_network_wired, eth_wire.tab_dns2, 200, 292);

    gtk_fixed_put((GtkFixed *)fix_network_wired, eth_wire.tab4_saveBtn, 408, 292);

    g_signal_connect_swapped(G_OBJECT(eth_wire.tab4_saveBtn), "clicked", G_CALLBACK(button_set_netcard), NULL);
    g_signal_connect(G_OBJECT(eth_wire.combo_DHCP), "changed", G_CALLBACK(changeDHCP), NULL);
    g_signal_connect(G_OBJECT(eth_wire.combo_netcard), "changed", G_CALLBACK(change_netcard), NULL);

    set_css(eth_wire.tab4_saveBtn, "button{ color: white;"
                                   "background:rgb(53,126,169);"
                                   "border:1px solid rgb(40,94,142);"
                                   "border-radius: 0px}");
    set_css(eth_wire.tab4_saveBtn, "button:hover{border-radius:0px;background: #3070a9}");

    return fix_network_wired;
}
